﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DFlowCore
{


    public static class ArraySliceExt
    {
        public static ArraySlice2D<T> Slice<T>(this T[,] arr, int firstDimension)
        {
            return new ArraySlice2D<T>(arr, firstDimension);
        }
    }

    public class ArraySlice2D<T>
    {
        private readonly T[,] arr;
        private readonly int firstDimension;
        private readonly int length;
        public int Length { get { return length; } }
        public ArraySlice2D(T[,] arr, int firstDimension)
        {
            this.arr = arr;
            this.firstDimension = firstDimension;
            this.length = arr.GetUpperBound(1) + 1;
        }
        public T this[int index]
        {
            get { return arr[firstDimension, index]; }
            set { arr[firstDimension, index] = value; }
        }
        public T[] ToArray()
        {
            T[] r = new T[this.length];
            for (int i = 0; i < this.length; i++)
            {
                r[i] = this.arr[this.firstDimension, i];
            }
            return r;
        }

    }



    public class SIMD
    {

        public class FAA
        {
            public static float[] Add(float[] fa1, float[] fa2)
            {
                float[] r = new float[fa1.Length];
                for (int i = 0; i < fa1.Length; i++)
                {
                    r[i] = fa1[i] + fa2[i];
                }
                return r;
            }


            public static float[] Diff(float[] fa1, float[] fa2)
            {
                float[] r = new float[fa1.Length];
                for (int i = 0; i < fa1.Length; i++)
                {
                    r[i] = fa1[i] - fa2[i];
                }
                return r;
            }

            public static float[] Div(float[] fa1, float[] fa2)
            {
                float[] r = new float[fa1.Length];
                for (int i = 0; i < fa1.Length; i++)
                {
                    r[i] = fa1[i] / fa2[i];
                }
                return r;
            }



            public static float[] Mul(float[] fa1, float[] fa2)
            {
                float[] r = new float[fa1.Length];
                for (int i = 0; i < fa1.Length; i++)
                {
                    r[i] = fa1[i] * fa2[i];
                }
                return r;
            }


            public static float[] Scale(float[] fa1, float f2)
            {
                float[] r = new float[fa1.Length];
                for (int i = 0; i < fa1.Length; i++)
                {
                    r[i] = fa1[i] * f2;
                }
                return r;
            }


            public static float Mag(float[] fa1)
            {
                float r = 0;
                for (int i = 0; i < fa1.Length; i++)
                {
                    r += (fa1[i] * fa1[i]);
                }
                return Mathf.Sqrt(r);
            }

            public static float SMag(float[] fa1)
            {
                float r = 0;
                for (int i = 0; i < fa1.Length; i++)
                {
                    r += (fa1[i] * fa1[i]);
                }
                return r;
            }
        }
		




    }
}
